home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / TUT10NEW.ZIP / GFX2.CPP < prev    next >
C/C++ Source or Header  |  1995-01-22  |  19KB  |  470 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. //                                                                         //
  3. // GFX2.CPP - VGA Trainer Program secondary module containing graphics     //
  4. //            functions.  Note: This module does not follow a lot of good  //
  5. //            programming practices.  It was built to be used with the     //
  6. //            VGA tutorial series.  If you are planning on using this      //
  7. //            module with a different source file, some modifications may  //
  8. //            be necessary.                                                //
  9. //                                                                         //
  10. // Author        : Grant Smith (Denthor) - denthor@beastie.cs.und.ac.za    //
  11. // Translator    : Christopher G. Mann   - r3cgm@dax.cc.uakron.edu         //
  12. //                                                                         //
  13. // Last Modified : January 21, 1995                                        //
  14. //                                                                         //
  15. /////////////////////////////////////////////////////////////////////////////
  16.  
  17. //               //
  18. // INCLUDE FILES //
  19. //               //
  20.  
  21.   #include <alloc.h>
  22.                            // farcalloc(), farfree()
  23.   #include <dos.h>
  24.                            // geninterrupt(), FP_SEG
  25.  
  26. //         //
  27. // DEFINES //
  28. //         //
  29.  
  30.   #if !defined(PI)
  31.     #define PI 3.1415927
  32.   #endif
  33.  
  34.   #if !defined(VGA)
  35.     #define VGA 0xA000
  36.   #endif
  37.  
  38. //          //
  39. // TYPEDEFS //
  40. //          //
  41.  
  42.   typedef unsigned char byte;
  43.   typedef unsigned int  word;
  44.  
  45. //                     //
  46. // FUNCTION PROTOTYPES //
  47. //                     //
  48.  
  49.   // SCREEN FUNCTIONS
  50.   void  SetUpVirtual(byte far *&Virscr, word &Vaddr);
  51.   void  ShutDown    (byte far *&Virscr);
  52.   void  Cls         (byte Col, word Where);
  53.   void  Flip        (word source, word dest);
  54.   void  WaitRetrace ();
  55.  
  56.   // MODE SETTING FUNCTIONS
  57.   void  SetMCGA     ();
  58.   void  SetText     ();
  59.  
  60.   // PALLETTE CLASS (DATA OBJECT AND RELATED FUNCTIONS)
  61.   class Pal {
  62.     public:
  63.       Pal();
  64.       void PalSet   (byte Rset, byte Gset, byte Bset);
  65.       void PalGet   (byte Col);
  66.       void PalPut   (byte Col);
  67.       void PalInc   ();
  68.       void PalDec   ();
  69.     private:
  70.       byte R;   // 0-63
  71.       byte G;   // 0-63
  72.       byte B;   // 0-63
  73.   };
  74.  
  75.   // MATH-LIKE FUNCTIONS
  76.   float rad         (float theta);
  77.   int   sgn         (int a);
  78.  
  79.   template<class T>
  80.   T abso(T value) {  if (value >= 0) return value;  else return -value; }
  81.  
  82.   // DRAWING FUNCTIONS
  83.   void  Putpixel    (word X, word Y, byte Col, word Where);
  84.   void  PutpixelVGA (word X, word Y, byte Col);
  85.   void  Line        (int a, int b, int c, int  d, int col, word Where);
  86.   void  Hline       (word X1, word X2, word Y, byte Col, word Where);
  87.  
  88.  
  89. //-------------------------VIRTUAL SCREEN FUNCTIONS------------------------//
  90.  
  91. /////////////////////////////////////////////////////////////////////////////
  92. //                                                                         //
  93. // SetUpVirtual() - This sets up the memory needed for a virtual screen.   //
  94. //                                                                         //
  95. /////////////////////////////////////////////////////////////////////////////
  96.  
  97. void SetUpVirtual(byte far *&Virscr, word &Vaddr) {
  98.   Virscr = (byte far *) farcalloc(64000,1);
  99.   Vaddr = FP_SEG(Virscr);
  100. }
  101.  
  102. /////////////////////////////////////////////////////////////////////////////
  103. //                                                                         //
  104. // ShutDown() - This frees the memory used by a virtual screen.            //
  105. //                                                                         //
  106. /////////////////////////////////////////////////////////////////////////////
  107.  
  108. void ShutDown(byte far *&Virscr) {
  109.   farfree(Virscr);
  110. }
  111.  
  112. /////////////////////////////////////////////////////////////////////////////
  113. //                                                                         //
  114. // Cls() - This clears the screen at Where to color Col.                   //
  115. //                                                                         //
  116. /////////////////////////////////////////////////////////////////////////////
  117.  
  118. void Cls(byte Col, word Where) {
  119.   asm {
  120.     push    es           // save ES
  121.     mov     cx, 32000    // this is our loop counter.  we want to clear
  122.                          //   64000 bytes of memory, so why do we use 32000?
  123.                          //   1 word = 2 bytes, and we are moving a word at
  124.                          //   a time
  125.     mov     es, [Where]  // move address in Where to ES
  126.     xor     di, di       // zero out DI
  127.     mov     al, [Col]    // move color to AL
  128.     mov     ah, al       // move color to AH (Remember, will be moving
  129.                          //   a WORDS, so we need two copies
  130.     rep     stosw        // copy AX to Where and drecrement CX by 1
  131.                          //   until CX equals 0
  132.     pop     es           // restore ES
  133.   }
  134. }
  135.  
  136. /////////////////////////////////////////////////////////////////////////////
  137. //                                                                         //
  138. // Flip() - This copies 64000 bytes from "source" to "destination".        //
  139. //                                                                         //
  140. /////////////////////////////////////////////////////////////////////////////
  141.  
  142. void Flip(word source, word dest) {
  143.   asm {
  144.     push    ds           // save DS
  145.     mov     ax, [dest]   // copy segment of destination to AX
  146.     mov     es, ax       // set ES to point to destination
  147.     mov     ax, [source] // copy segment of source to AX
  148.     mov     ds, ax       // set DS to point to source
  149.     xor     si, si       // zero out SI
  150.     xor     di, di       // zero out DI
  151.     mov     cx, 32000    // set our counter to 32000
  152.     rep     movsw        // move source to destination by words.  decrement
  153.                          //   CX by 1 each time until CX is 0
  154.     pop     ds           // restore DS
  155.   }
  156. }
  157.  
  158. /////////////////////////////////////////////////////////////////////////////
  159. //                                                                         //
  160. // WaitRetrace() - This waits until you are in a Verticle Retrace.         //
  161. //                                                                         //
  162. /////////////////////////////////////////////////////////////////////////////
  163.  
  164. void WaitRetrace() {
  165.  
  166.   _DX = 0x03DA;
  167.  
  168.   l1: asm {
  169.     in  al,dx;
  170.     and al,0x08;
  171.     jnz l1;
  172.       }
  173.  
  174.   l2: asm {
  175.     in  al,dx;
  176.     and al,0x08;
  177.     jz  l2;
  178.       }
  179. }
  180.  
  181. //--------------------------MODE SETTING FUNCTIONS-------------------------//
  182.  
  183. /////////////////////////////////////////////////////////////////////////////
  184. //                                                                         //
  185. // SetMCGA() - This function gets you into 320x200x256 mode.               //
  186. //                                                                         //
  187. /////////////////////////////////////////////////////////////////////////////
  188.  
  189. void SetMCGA() {
  190.   _AX = 0x0013;
  191.   geninterrupt (0x10);
  192. }
  193.  
  194. /////////////////////////////////////////////////////////////////////////////
  195. //                                                                         //
  196. // SetText() - This function gets you into text mode.                      //
  197. //                                                                         //
  198. /////////////////////////////////////////////////////////////////////////////
  199.  
  200. void SetText() {
  201.   _AX = 0x0003;
  202.   geninterrupt (0x10);
  203. }
  204.  
  205.  
  206. //----------------------------PALLETTE FUNCTIONS---------------------------//
  207.  
  208. /////////////////////////////////////////////////////////////////////////////
  209. //                                                                         //
  210. // Pal() - This constructor initializes all Pal variables (R, G, and B) to //
  211. //         zero.  This ensures that all Pal objects start in a consistent  //
  212. //         state.                                                          //
  213. //                                                                         //
  214. /////////////////////////////////////////////////////////////////////////////
  215.  
  216. Pal::Pal() { R = B = G = 0; }
  217.  
  218. /////////////////////////////////////////////////////////////////////////////
  219. //                                                                         //
  220. // PalSet() - This sets the Red, Green, and Blue values of a given color.  //
  221. //            Set invalid colors ( >63 ) equal to 0.                       //
  222. //                                                                         //
  223. /////////////////////////////////////////////////////////////////////////////
  224.  
  225. void Pal::PalSet(byte Rset, byte Gset, byte Bset) {
  226.  
  227.    R = (Rset < 64) ? Rset : 0;
  228.    G = (Gset < 64) ? Gset : 0;
  229.    B = (Bset < 64) ? Bset : 0;
  230.  
  231. }
  232.  
  233. /////////////////////////////////////////////////////////////////////////////
  234. //                                                                         //
  235. // PalGet() - This reads the values of the Red, Green, and Blue values of  //
  236. //            a certain color.                                             //
  237. //                                                                         //
  238. /////////////////////////////////////////////////////////////////////////////
  239.  
  240. void Pal::PalGet(byte Col) {
  241.  
  242.   byte Rtemp, Gtemp, Btemp;
  243.  
  244.   asm {
  245.     mov     dx, 0x03C7   // load DX with 3C7 (read pallette function)
  246.     mov     al, [Col]    // move color to AL
  247.     out     dx, al       // write DX to the VGA (tell VGA that we want to
  248.                          //   work with the color in AL
  249.     add     dx, 2        // load DX with 3C9 (read RGB colors)
  250.     in      al, dx       // read Red   to AL
  251.     mov     [Rtemp],al   // copy AL to rr
  252.     in      al, dx       // read Green to AL
  253.     mov     [Gtemp],al   // copy AL to gg
  254.     in      al, dx       // read Blue  to AL
  255.     mov     [Btemp],al   // copy AL to bb
  256.   }
  257.  
  258.   R = Rtemp;
  259.   G = Gtemp;
  260.   B = Btemp;
  261.  
  262. }
  263.  
  264. /////////////////////////////////////////////////////////////////////////////
  265. //                                                                         //
  266. // PalPut() - This sets the Red, Green, and Blue values of a color.        //
  267. //                                                                         //
  268. /////////////////////////////////////////////////////////////////////////////
  269.  
  270. void Pal::PalPut (byte Col) {
  271.  
  272.   byte Rtemp = R, Gtemp = G, Btemp = B;
  273.  
  274.   asm {
  275.     mov     dx, 0x3C8    // load DX with 3C8 (write pallette function)
  276.     mov     al, [Col]    // move color to AL
  277.     out     dx, al       // write DX to the VGA (tell VGA that we want to
  278.                          //   work with the color in AL
  279.     inc     dx           // load DX with 3C9 (write RGB colors)
  280.     mov     al, [Rtemp]  // move Red   to AL
  281.     out     dx, al       // write DX to VGA (tell VGA that we want to use
  282.                          //   the Red value in AL
  283.     mov     al, [Gtemp]  // move Green to AL
  284.     out     dx, al       // write DX to VGA
  285.     mov     al, [Btemp]  // move Blue  to AL
  286.     out     dx, al       // write DX to VGA
  287.   }
  288. }
  289.  
  290. /////////////////////////////////////////////////////////////////////////////
  291. //                                                                         //
  292. // PalInc() - This increments the R, G, and B values of a given Pal        //
  293. //            variable, keeping all values less than 64.                   //
  294. //                                                                         //
  295. /////////////////////////////////////////////////////////////////////////////
  296.  
  297. void Pal::PalInc() {
  298.  
  299.   // if (R < 63) R = R + 1; else R = 63;
  300.   R = (R < 63) ? (R + 1) : 63;
  301.   G = (G < 63) ? (G + 1) : 63;
  302.   B = (B < 63) ? (B + 1) : 63;
  303.  
  304. }
  305.  
  306. /////////////////////////////////////////////////////////////////////////////
  307. //                                                                         //
  308. // PalDec() - This decrements the R, G, and B values of a given Pal        //
  309. //            variable, keeping all values greater than or equal to zero.  //
  310. //                                                                         //
  311. /////////////////////////////////////////////////////////////////////////////
  312.  
  313. void Pal::PalDec() {
  314.  
  315.   // if (R > 0) R = R - 1; else R = 0;
  316.   R = (R > 0) ? (R - 1) : 0;
  317.   G = (G > 0) ? (G - 1) : 0;
  318.   B = (B > 0) ? (B - 1) : 0;
  319.  
  320. }
  321.  
  322.  
  323. //----------------------------MATH-LIKE FUNCTIONS--------------------------//
  324.  
  325. /////////////////////////////////////////////////////////////////////////////
  326. //                                                                         //
  327. // rad() - This calculates the degrees of an angle.                        //
  328. //                                                                         //
  329. /////////////////////////////////////////////////////////////////////////////
  330.  
  331. float rad(float theta) {
  332.   return ((theta * PI)/180);
  333. }
  334.  
  335. /////////////////////////////////////////////////////////////////////////////
  336. //                                                                         //
  337. // sgn() - This checks the sign of an integer and returns a 1, -1, or 0.   //
  338. //                                                                         //
  339. /////////////////////////////////////////////////////////////////////////////
  340.  
  341. int sgn (int a) {
  342.  
  343.   if (a > 0)  return +1;
  344.   if (a < 0)  return -1;
  345.   return 0;
  346. }
  347.  
  348.  
  349. //-----------------------------DRAWING FUNCTIONS---------------------------//
  350.  
  351. /////////////////////////////////////////////////////////////////////////////
  352. //                                                                         //
  353. // Putpixel() - This puts a pixel on the screen by writing directly to     //
  354. //              memory.                                                    //
  355. //                                                                         //
  356. /////////////////////////////////////////////////////////////////////////////
  357.  
  358. void Putpixel (word X, word Y, byte Col, word Where) {
  359.   asm {
  360.     mov     ax, [Where]  // move segment of Where to AX
  361.     mov     es, ax       // ES = VGA
  362.     mov     bx, [X]      // BX = X
  363.     mov     dx, [Y]      // DX = Y
  364.     mov     ah, dl       // AH = Y*256
  365.     xor     al, al       // AX = Y*256
  366.     shl     dx, 6        // DX = Y*64
  367.     add     dx, ax       // DX = Y*320
  368.     add     bx, dx       // BX = Y*320 + X
  369.     mov     ah, [Col]    // move value of Col into AH
  370.     mov     byte ptr es:[bx], ah  // move Col to the offset in memory (DI)
  371.   }
  372. }
  373.  
  374. /////////////////////////////////////////////////////////////////////////////
  375. //                                                                         //
  376. // PutpixelVGA() - This puts a pixel on the screen by writing directly to  //
  377. //                 VGA memory.                                             //
  378. //                                                                         //
  379. /////////////////////////////////////////////////////////////////////////////
  380.  
  381. void PutpixelVGA (word X, word Y, byte Col) {
  382.   asm {
  383.     mov     ax, 0xA000   // AX = VGA Segment
  384.     mov     es, ax       // ES = VGA Segment
  385.     mov     bx, [X]      // BX = X
  386.     mov     dx, [Y]      // DX = Y
  387.     mov     ah, dl       // AX = Y*256 (AL is already 0 from A000 address)
  388.     shl     dx, 6        // DX = Y*64
  389.     add     dx, ax       // DX = Y*320
  390.     add     bx, dx       // BX = Y*320 + X
  391.     mov     ah, [Col]    // move value of Col into AH
  392.     mov     byte ptr es:[bx], ah  // move Col to the offset in memory (DI)
  393.   }
  394. }
  395.  
  396. /////////////////////////////////////////////////////////////////////////////
  397. //                                                                         //
  398. // Line() - This draws a line from a,b to c,d of color col on screne Where //
  399. //                                                                         //
  400. /////////////////////////////////////////////////////////////////////////////
  401.  
  402. void Line(int a, int b, int c, int d, int col, word Where) {
  403.  
  404.   int i,u,s,v,d1x,d1y,d2x,d2y,m,n;
  405.  
  406.   u   = c-a;       // x2-x1
  407.   v   = d-b;       // y2-y1
  408.   d1x = sgn(u);    // d1x is the sign of u (x2-x1) (VALUE -1,0,1)
  409.   d1y = sgn(v);    // d1y is the sign of v (y2-y1) (VALUE -1,0,1)
  410.   d2x = sgn(u);    // d2x is the sign of u (x2-x1) (VALUE -1,0,1)
  411.   d2y = 0;
  412.   m   = abso(u);   // m is the distance between x1 and x2
  413.   n   = abso(v);   // n is the distance between y1 and y2
  414.  
  415.   if (m<=n) {      // if the x distance is greater than the y distance
  416.     d2x = 0;
  417.     d2y = sgn(v);  // d2y is the sign of v (x2-x1) (VALUE -1,0,1)
  418.     m   = abso(v); // m is the distance between y1 and y2
  419.     n   = abso(u); // n is the distance between x1 and x2
  420.   }
  421.  
  422.   s = m / 2; // s is the m distance (either x or y) divided by 2
  423.  
  424.   for (i=0;i<m+1;i++) { // repeat this loop until it
  425.                  // is = to m (y or x distance)
  426.     Putpixel(a,b,col,Where); // plot a pixel at the original x1, y1
  427.     s += n;                  // add n (dis of x or y) to s (dis of x of y)
  428.     if (s >= m) {            // if s is >= m (distance between y1 and y2)
  429.       s -= m;
  430.       a += d1x;
  431.       b += d1y;
  432.     }
  433.     else {
  434.       a += d2x;
  435.       b += d2y;
  436.     }
  437.   }
  438.  
  439. }
  440.  
  441. /////////////////////////////////////////////////////////////////////////////
  442. //                                                                         //
  443. // Hline() - This draws a horizontal line from X1 to X2 on line Y in color //
  444. //           Col at memory location Where.                                 //
  445. //                                                                         //
  446. /////////////////////////////////////////////////////////////////////////////
  447.  
  448. void Hline (word X1, word X2, word Y, byte Col, word Where) {
  449.   asm {
  450.     mov     ax, [Where]  // move segment of Where to AX
  451.     mov     es, ax       // set ES to segment of Where
  452.     mov     ax, [Y]      // set AX to Y
  453.     mov     di, ax       // set DI to Y
  454.     shl     ax, 8        // shift AX left 8 places (multiply Y by 256)
  455.     shl     di, 6        // shift DI left 6 places (multiply Y by 64)
  456.     add     di, ax       // add AX to DI (Y*64 + Y*256 = Y*320)
  457.     add     di, [X1]     // add the X1 offset to DI
  458.     mov     al, [Col]    // move Col to AL
  459.     mov     ah, al       // move Col to AH (we want 2 copies for word moving)
  460.     mov     cx, [X2]     // move X2 to CX
  461.     sub     cx, [X1]     // move the change in X to CX
  462.     shr     cx, 1        // divide change in X by 2 (for word moving)
  463.     jnc     Start        // if we have an even number of moves, go to Start
  464.     stosb                // otherwise, move one byte more
  465.   }
  466.   Start: asm {
  467.     rep     stosw        // do it!
  468.   }
  469. }
  470.